package kr.pe.xissy.soulmate.service;

import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;

import kr.pe.xissy.soulmate.domain.User;
import kr.pe.xissy.soulmate.domain.Work;
import kr.pe.xissy.soulmate.helper.DateHelper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.keyvalue.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class WorkService extends SoulMateService {

	@Autowired
	public WorkService(StringRedisTemplate redisTemplate) {
		super(redisTemplate);
	}

	protected String getKeyString(User user) {
		return getKeyString(user.getEmail());
	}

	protected String getKeyString(String email) {
		return super.getKeyStringPrefix() + email + ":work";
	}

	public Collection<Work> findAllByEmailAndDateBetween(String email, boolean containsPrivate, Date startDate, Date endDate) {
		String keyString = getKeyString(email) + ":sortedIdSet";
		Set<String> sortedIdSet = zSetOperations.rangeByScore(keyString, DateHelper.parseDateToDouble(startDate), DateHelper.parseDateToDouble(endDate));

		Set<Work> workSet = new TreeSet<Work>();

		for (String id : sortedIdSet) {
			try {
				Date date = DateHelper.parseDate(valueOperations.get(getKeyString(email) + ":" + id + ":date"));
				String text = valueOperations.get(getKeyString(email) + ":" + id + ":text");
				boolean isPrivate = Boolean.parseBoolean(valueOperations.get(getKeyString(email) + ":" + id + ":isPrivate"));

				if (!isPrivate || (containsPrivate && isPrivate)) {
					workSet.add(new Work(Integer.parseInt(id), isPrivate, date, text));
				}

			} catch (Exception e) {
				continue;
			}
		}

		return workSet;
	}

	public Collection<Work> findAllByEmail(String email, boolean containsPrivate) {
		return findAllByEmailAndDateBetween(email, containsPrivate, new Date(0), new Date(Long.MAX_VALUE));
	}

	public Collection<Work> findAllByEmailAndToday(String email, boolean containsPrivate) {
		return findAllByEmailAndDateBetween(email, containsPrivate, DateHelper.getTodayStartDate(), DateHelper.getTomorrowStartDate());
	}

	public Collection<Work> findAllByUserAndDateBetween(User user, boolean containsPrivate, Date startDate, Date endDate) {
		return findAllByEmailAndDateBetween(user.getEmail(), containsPrivate, startDate, endDate);
	}

	public Collection<Work> findAllByUserAndToday(User user, boolean containsPrivate) {
		return findAllByUserAndDateBetween(user, containsPrivate, DateHelper.getTodayStartDate(), DateHelper.getTomorrowStartDate());
	}

	public void save(User user, Work work) {
		Long nextId = valueOperations.increment(getKeyString(user) + ":nextId", 1);
		zSetOperations.add(getKeyString(user) + ":sortedIdSet", nextId.toString(), DateHelper.parseDateToDouble(work.getDate()));

		valueOperations.set(getKeyString(user) + ":" + nextId.toString() + ":date", DateHelper.parseDateToString(work.getDate()));
		valueOperations.set(getKeyString(user) + ":" + nextId.toString() + ":text", work.getText());
		valueOperations.set(getKeyString(user) + ":" + nextId.toString() + ":isPrivate", String.valueOf(work.isPrivate()));
	}

}
